#pragma once
#include <iostream>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define PATHNAME "." // 当前路径（路径都行）
#define PROJ_ID 0X3f // 项目id也无要求
#define MAX_SIZE 4096
key_t getKey()
{
    key_t k = ftok(PATHNAME, PROJ_ID);
    if (k == -1)
    {
        std::cout << "ftok" << errno << ":" << strerror(errno) << std::endl;
        exit(1);
    }
    return k;
}
int getShmHelper(key_t key, int flags)
{
    int shmid = shmget(key, MAX_SIZE, flags);
    if (shmid == -1) // 创建共享内存失败
    {
        std::cerr << "shmget" << errno << ":" << strerror(errno) << std::endl;
        exit(2);
    }
    return shmid; // 返回共享内存标识符
}
int getShm(key_t key) // 创建或者获取共享内存
{
    return getShmHelper(key, IPC_CREAT); // 传0也行
}
int createShm(key_t key) // 必定创建共享内存
{
    return getShmHelper(key, IPC_CREAT | IPC_EXCL | 0600); // 生成一个全新的共享内存
}
void *attachShm(int shmid) // 让共享内存与虚拟内存建立联系
{
    void *memstart = shmat(shmid, nullptr, 0);
    if ((long long)memstart == -1L)
    {
        std::cerr << "shmat" << errno << ":" << strerror << std::endl;
        exit(3);
    }
    return memstart;
}
void detchShm(void *memStart) // 去关联
{
    if (shmdt(memStart) == -1)
    {
        std::cerr << "shmdt" << errno << ":" << strerror << std::endl;
        exit(4);
    }
}
void delShm(int shmid) // 删除共享内存
{
    if (shmctl(shmid, IPC_RMID, nullptr) == -1)
    {
        std::cerr << "shmctl" << errno << ":" << strerror << std::endl;
    }
}